﻿package vklib
{
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.getQualifiedClassName;	
	import flash.utils.describeType;
	/**
	 * ...
	 * @author apisoc@gmail.com
	 */
	public class VkApi
	{
		public static const BUTTON_LINK:uint = 0;
		public static const BUTTON_BLUE:uint = 1;
		public static const BUTTON_GRAY:uint = 2;
		public static const BUTTON_TEXT_ALIGN_CENTER:uint = 0;
		public static const BUTTON_TEXT_ALIGN_LEFT:uint = 1;
		public static const BUTTON_TEXT_ALIGN_RIGHT:uint = 2;

		public static const PAGINATION_RECT_AS_SEL:uint = 0x0001;
		public static const PAGINATION_RIGHT_ALIGNED:uint = 0x0002;
	    
		public static const COLOR_BK:int = 0xf7f7f7;
		public static const COLOR_BK_BLUE:int = 0xdae1e8;
		public static const COLOR_TXT_BLUE:int = 0x36638e;
		public static const COLOR_BORDER:int = 0xd8dfea;
		public static const COLOR_BORDER2:int = 0xc0cad5;
		public static const COLOR_ARROW_BG:int = 0xe1e8ed;
		public static const COLOR_ARROW_BG_BORDER:int = 0xd2dbe0;
		public static const COLOR_SEL_BG:int = 0x5f83a5;
		public static const COLOR_SEL_BG_BORDER:int = 0x345f88;
		public static const COLOR_BUT1_TXT:int = 0x2b587a;
		public static const COLOR_RED:int = 0xff0000;
		
		public static const COLORS_LIGHT_BUTTON:Array = [0xf4ebbd, 0xf6f0d6, 0x908851, 0x908851];

		public static const TXT_UNDERLINE:int = 0x0001;
		public static const TXT_BOLD:int = 0x0002;
		public static const TXT_MULTILINE:int = 0x0004;
		public static const TXT_CENTER:int = 0x0008;
		public static const TXT_AUTOSIZE:int = 0x0010;
		public static const TXT_INPUT:int = 0x0020;
		public static const TXT_BORDER:int = 0x0040;
		public static const TXT_HTML:int = 0x0080;

		public static const SETTINGS_DEFAULT_MODE:uint = 0;
		public static const SETTINGS_LOCAL_MODE:uint = 1;
		public static const SETTINGS_DEBUG_MODE:uint = 2;
		public static const SETTINGS_OFFLINE_MODE:uint = 4;
		
		
		private var _wrapper:IVkWrapper = null;
		private var _factory:IVkGuiFactory = null;
		private var _request:IVkRequest = null;
		
		private static var _instance:VkApi;
		private static var _instReady:Boolean = true;
		private static var _settings:Object = { secret: '', mode: SETTINGS_DEFAULT_MODE };
		
		private var _counter:uint = 0;
		
			
		public static function createInstance(main:IVkMain):void
		{
			if (!_instance) {
				_instReady = false; 
				_instance = new VkApi(main);
				_instReady = true;
            }
			++_instance._counter;
		}
		
		public static function get instance():VkApi
		{		
			debugAssert(_instance != null);
			return _instance;
		}
		public static function get settings():Object { return _settings; }
		
		public function get counter():uint { return _counter; }
		
		public static function hasMode(m:uint):Boolean { return m == (m & _settings.mode); }
		
		public function VkApi(main:IVkMain)
		{
			VkApi.debugAssert(main is vklib.VkMain); // Only VkMain inherited can start wrapper initialing
			var mainSprite:VkMain = main as VkMain; // Not const because addListener
			VkApi.debugAssert(!_instReady && mainSprite.sprite); // _instReady mutex lock
			
			const init:Function = function():void {
				_request = new VkRequest(_wrapper.parameters);
				var result:IResult = new LoaderResult(hasMode(SETTINGS_OFFLINE_MODE) ?
					'vk_gui-0.5.swf' :'http://api.vkontakte.ru/swf/vk_gui-0.5.swf');
				result.onSuccess = function(data:LoaderInfo):void {
					_factory = new GuiFactory(data);
					main.run();
				}
				result.load();
			}
			
			// Load VkWrapper from Sprite or vk APIWrapper() (http://vkontakte.ru/pages.php?id=6808516)
  			if (hasMode(SETTINGS_LOCAL_MODE)) {
				try { 
					_wrapper = new VkWrapper(mainSprite);
					init();
				} catch (e:Error) { 
					debug(e);
				}
			} else {
				// Load WkWrapper from Flash Container data params
				const onInit:Function = function(e:Event):void {
					try {
						e.target.removeEventListener(e.type, onInit);
						_wrapper = new VkWrapper(mainSprite.parent.parent);
						init();
					} catch (e:Error) { 
						debug(e); 
					}
				}
				mainSprite.addEventListener(Event.ADDED_TO_STAGE, onInit);
			}
			
		}

		public function get wrapper():IVkWrapper { return _wrapper; }
				
		public function get guiFactory():IVkGuiFactory { return _factory; }
		public function get guiUtils():* { return (_factory as GuiFactory).classByName('Utils'); }
		
				
		public function get request():IVkRequest { return _request; }
		
		private static function dump(obj:Object):String
		{
			var ret:String = describeType(obj);
			for (var p:String in obj)
				ret += '\n' + p + ' = ' + obj[p];
			return ret;
		}
		
		public static function debugAssert(assertionOnFalse:Boolean, msg:String = ''):void
		{
			if (!assertionOnFalse)
				throw Error('AssertException. ' + msg);
		}
		
		public static function debug(param:*, caller:* = null):void
		{
			// exclude dump call
			var msg:String = (null == param ? 'NULL' 
					: (param is String ? param 
						: (param is Error ? (param as Error).getStackTrace()
							: dump(param))));
			if (caller) msg = getQualifiedClassName(caller) + ' - ' + msg;
							

			if (_instReady && _instance.wrapper)
				_instance.wrapper.external.debug(msg);
			else
				trace(msg);
		}
		
		public static function trim(s:String):String
		{
			return s.replace(/^\s+|\s+$/g, '');
		}
		
		
		public static function sendExternal(url:String):void
		{
			//var request:URLRequest = new URLRequest(url);
			//request.method = 'GET';
			//request.
		}
		public function loadXml(name:String):XML
		{
			var ret:XML = new XML();
			const path:Array = name.split('.');
			debug(path);
			return ret;
		}
		
		public function load(name:String):*
		{
			var ret:* = null;
			//debug(name.split(/\s*(\w+)\s*\.+\s*(\w+)\s*/));
				//ret.addItem(v);
			
			if (name.indexOf('Menu') > 0)
				ret = VkApi.instance.guiFactory.createMainMenu();
			return ret;
		}
	}
}
